$import( "SmitearWebGL.Programs.AbstractProgram" );

SmitearWebGL.Programs.Hdr.LuminanceProgram = SmitearWebGL.Programs.AbstractProgram.extend(
{
	/******** constructor ********/
	
	init : function()
	{
		this._super();
		this._registClass( "SmitearWebGL.Programs.Hdr.LuminanceProgram" );
	}
	,
	
	/******** public method ********/
	
	activeUniform : function( renderableObject )
	{
		this.context.gl.uniformMatrix4fv( this._shader.uniforms.tcLumOffsets.location, false, renderableObject._offsets );
		
		var texture = renderableObject.getTextureAt( 0 );
		this.context.gl.activeTexture( this.context.gl.TEXTURE0 );
		this.context.gl.bindTexture( this.context.gl.TEXTURE_2D, texture.getGlTexture() );
		this.context.gl.uniform1i( this._shader.uniforms.uSampler.location, 0 );
		
		return SmitearWebGL.Core.HResult.SUCCESS;
	}
	,
	
	/******** private method ********/
	
	_generateVertexShaderStr : function()
	{
		this._super();
		
		var vertStr =
		"\
		attribute vec3 " + SmitearWebGL.Resources.Buffer.AttribLocation.POSITION +";\n\
		varying vec2 vTexCoord;\n\
		void main(void)\n\
		{\n\
			vec4 pos = vec4(" + SmitearWebGL.Resources.Buffer.AttribLocation.POSITION +", 1.0);\n\
			gl_Position = pos;\n\
			vTexCoord = vec2((pos.x + 1.0) * 0.5, (pos.y + 1.0) * 0.5);\n\
		}\n\
		";
		
		return vertStr;
	}
	,
	_generateFragmentShaderStr : function()
	{
		this._super();
		
		var fragStr = "";
		
		if ( this.context.capacity.supported.OES_texture_float )
		{
			fragStr = 
			"\
			#ifdef GL_ES\n\
			precision highp float;\n\
			#endif\n\
			uniform sampler2D uSampler;\n\
			uniform mat4 tcLumOffsets;\n\
			varying vec2 vTexCoord;\n\
			const vec4 lumfact = vec4(0.27,0.67,0.06,0.0);\n\
			void main(void) {\n\
				vec4 color = vec4(0.0, 0.0, 0.0, 0.0);\n\
				float average = 0.0;\n\
				float maximum = -1e20;\n\
				vec2 offsets[4];\n\
				offsets[0] = vec2(tcLumOffsets[0][0], tcLumOffsets[0][1]);\n\
				offsets[1] = vec2(tcLumOffsets[1][0], tcLumOffsets[1][1]);\n\
				offsets[2] = vec2(tcLumOffsets[2][0], tcLumOffsets[2][1]);\n\
				offsets[3] = vec2(tcLumOffsets[3][0], tcLumOffsets[3][1]);\n\
				for( int i = 0; i < 4; i++ )\n\
				{\n\
					color = texture2D( uSampler, vTexCoord + offsets[i] );\n\
					float greyValue = dot(color, lumfact);\n\
					maximum = max( maximum, greyValue );\n\
					average += ( 0.25 * log( 1e-5 + greyValue ) );\n\
				}\n\
				average = exp( average );\n\
				gl_FragColor = vec4( average, maximum, 1.0, 1.0 );\n\
			}\n\
			";
		}
		else
		{
			fragStr = 
			"\
			#ifdef GL_ES\n\
			precision highp float;\n\
			#endif\n\
			uniform sampler2D uSampler;\n\
			uniform mat4 tcLumOffsets;\n\
			varying vec2 vTexCoord;\n\
			const vec4 lumfact = vec4(0.27,0.67,0.06,0.0);\n\
			void main(void) {\n\
				vec4 color = vec4(0.0, 0.0, 0.0, 0.0);\n\
				float average = 0.0;\n\
				float b = 1.0;\n\
				float a = 1.0;\n\
				float maximum = -1e20;\n\
				vec2 offsets[4];\n\
				offsets[0] = vec2(tcLumOffsets[0][0], tcLumOffsets[0][1]);\n\
				offsets[1] = vec2(tcLumOffsets[1][0], tcLumOffsets[1][1]);\n\
				offsets[2] = vec2(tcLumOffsets[2][0], tcLumOffsets[2][1]);\n\
				offsets[3] = vec2(tcLumOffsets[3][0], tcLumOffsets[3][1]);\n\
				for( int i = 0; i < 4; i++ )\n\
				{\n\
					color = texture2D( uSampler, vTexCoord + offsets[i] );\n\
					color.rgb /= color.a;\n\
					float greyValue = dot(color, lumfact);\n\
					maximum = max( maximum, greyValue );\n\
					average += ( 0.25 * log( 1e-5 + greyValue ) );\n\
				}\n\
				average = exp( average );\n\
				if ( average > 1.0 )\n\
				{\n\
					b = 1.0 / average;\n\
					average = 1.0; \n\
				}\n\
				if ( maximum > 1.0 )\n\
				{\n\
					a = 1.0 / maximum;\n\
					maximum = 1.0; \n\
				}\n\
				gl_FragColor = vec4( average, maximum, b, a );\n\
			}\n\
			";
		}
			
		return fragStr;
	}
}
);